﻿namespace VividKit.ServiceModel
{
    using System;
    using System.Diagnostics;
    using System.Threading.Tasks;

    public class TraceEventDispatcher : IEventDispatcher
    {
        private readonly IEventDispatcher eventDispatcher;
        private readonly TraceSource log;

        public TraceEventDispatcher(IEventDispatcher eventDispatcher)
        {
            this.eventDispatcher = eventDispatcher;
            this.log = new TraceSource(this.eventDispatcher.GetType().Name, SourceLevels.Information);
        }

        public async Task PublishAsync<TEvent>(TEvent e) where TEvent : class, IEvent
        {
            var stopwatch = new Stopwatch();
            try
            {
                this.log.TraceEvent(TraceEventType.Information, 0, "Publishing {0}", e.GetType().Name);
                this.log.TraceObject(TraceEventType.Verbose, 0, e);
                stopwatch.Start();
                await this.eventDispatcher.PublishAsync(e);
            }
            catch (Exception x)
            {
                this.log.TraceData(TraceEventType.Warning, 0, x);
                throw;
            }
            finally
            {
                stopwatch.Stop();
                this.log.TraceEvent(TraceEventType.Information, 0, "Published {0} ({1} ms)",
                    e.GetType().Name, stopwatch.ElapsedMilliseconds);
            }
        }
    }
}